// ArkUICustomContainerNode.h
// 自定义容器组件示例

#ifndef MYAPPLICATION_ARKUICUSTOMCONTAINERNODE_H
#define MYAPPLICATION_ARKUICUSTOMCONTAINERNODE_H

#include "ArkUINode.h"
#include <hilog/log.h>

namespace NativeModule {

class ArkUICustomContainerNode : public ArkUINode {
public:
    // 使用自定义组件类型ARKUI_NODE_CUSTOM创建组件。
    ArkUICustomContainerNode()
        : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODE_CUSTOM))
    {
        // 注册自定义事件监听器。
        nativeModule_->addNodeCustomEventReceiver(handle_, OnStaticCustomEvent);
        // 声明自定义事件并转递自身作为自定义数据。
        nativeModule_->registerNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE, 0, this);
        nativeModule_->registerNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_LAYOUT, 0, this);
        
//         nativeModule_->addNodeEventReceiver(handle_,OnStaticNodeEvent);
//         nativeModule_->registerNodeEvent(handle_,NODE_EVENT_ON_AREA_CHANGE,0,this);
    }

    ~ArkUICustomContainerNode() override
    {
        // 反注册自定义事件监听器。
        nativeModule_->removeNodeCustomEventReceiver(handle_, OnStaticCustomEvent);
        // 取消声明自定义事件。
        nativeModule_->unregisterNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE);
        nativeModule_->unregisterNodeCustomEvent(handle_, ARKUI_NODE_CUSTOM_EVENT_ON_LAYOUT);
        
//         nativeModule_->removeNodeEventReceiver(handle_,OnStaticNodeEvent);
//         nativeModule_->unregisterNodeEvent(handle_, NODE_EVENT_ON_AREA_CHANGE);
        // NODE_EVENT_ON_APPEAR
        // NODE_EVENT_ON_AREA_CHANGE
    }

    void SetPadding(int32_t padding)
    {
        padding_ = padding;
        // 自定义属性事件更新需要主动调用标记脏区接口。
        nativeModule_->markDirty(handle_, NODE_NEED_MEASURE);
    }

private:
    static void OnStaticCustomEvent(ArkUI_NodeCustomEvent *event)
    {
        // 获取组件实例对象，调用相关实例方法。
        auto customNode = reinterpret_cast<ArkUICustomContainerNode *>(OH_ArkUI_NodeCustomEvent_GetUserData(event));
        auto type = OH_ArkUI_NodeCustomEvent_GetEventType(event);
        switch (type) {
            case ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE :
                customNode->OnMeasure(event);
                break;
            case ARKUI_NODE_CUSTOM_EVENT_ON_LAYOUT :
                customNode->OnLayout(event);
                break;
            default :
                break;
        }
    }

    static void OnStaticNodeEvent(ArkUI_NodeEvent *event)
    {
        // 获取组件实例对象，调用相关实例方法。
        auto customNode = reinterpret_cast<ArkUICustomContainerNode *>(OH_ArkUI_NodeEvent_GetUserData(event));
        auto type = OH_ArkUI_NodeEvent_GetEventType(event);
        switch (type) {
            case NODE_EVENT_ON_AREA_CHANGE :
                customNode->OnDisplay(event);
                break;
            default :
                break;
        }
    }

    void OnDisplay(ArkUI_NodeEvent *event)
    {
//         auto GetDis = OH_ArkUI_NodeEvent_GetUserData(event);
        auto dddd = OH_ArkUI_NodeEvent_GetNodeComponentEvent(event);
//         /Users/lalhan/Desktop/ContentSlotDrawing/entry/src/main/cpp/ContentSlot/ArkUIBaseNode.h
        DRAWING_LOGE("\n\n\n目标元素的原始高度：%{public}f", dddd->data[1].f32);
        DRAWING_LOGE("\n\n\n目标元素左上角相对于页面的原始Y坐标：%{public}f", dddd->data[5].f32);

        DRAWING_LOGE("\n\n\n目标元素左上角相对于页面的新Y坐标：%{public}f", dddd->data[11].f32);
//         DRAWING_LOGE("\n\n\n当前已经不可见了！！！！！！！！！");
    }

    // 自定义测算逻辑。
    void OnMeasure(ArkUI_NodeCustomEvent *event)
    {
        auto layoutConstrain = OH_ArkUI_NodeCustomEvent_GetLayoutConstraintInMeasure(event);
        // 创建子节点布局限制，复用父组件布局中的百分比参考值。
        auto childLayoutConstrain = OH_ArkUI_LayoutConstraint_Copy(layoutConstrain);
        OH_ArkUI_LayoutConstraint_SetMaxHeight(childLayoutConstrain, 1000);
        OH_ArkUI_LayoutConstraint_SetMaxWidth(childLayoutConstrain, 1000);
        OH_ArkUI_LayoutConstraint_SetMinHeight(childLayoutConstrain, 0);
        OH_ArkUI_LayoutConstraint_SetMinWidth(childLayoutConstrain, 0);

        // 测算子节点获取子节点最大值。
        auto totalSize = nativeModule_->getTotalChildCount(handle_);

        int32_t maxWidth = 0;
        int32_t maxHeight = 0;
        for (uint32_t i = 0; i < totalSize; i++) {
            auto child = nativeModule_->getChildAt(handle_, i);
            // 调用测算接口测算Native组件。
            nativeModule_->measureNode(child, childLayoutConstrain);
            auto size = nativeModule_->getMeasuredSize(child);
            if (size.width > maxWidth) {
                maxWidth = size.width;
            }
            if (size.height > maxHeight) {
                maxHeight = size.height;
            }
        }
        // 自定义测算为所有子节点大小加固定边距。
        nativeModule_->setMeasuredSize(handle_, maxWidth + 2 * padding_, maxHeight + 2 * padding_);
    }

    void OnLayout(ArkUI_NodeCustomEvent *event)
    {
        // 获取父组件期望位置并设置。
        auto position = OH_ArkUI_NodeCustomEvent_GetPositionInLayout(event);

        nativeModule_->setLayoutPosition(handle_, position.x, position.y);
        // 设置子组件居中对齐。
        auto totalSize = nativeModule_->getTotalChildCount(handle_);

        auto selfSize = nativeModule_->getMeasuredSize(handle_);

        for (uint32_t i = 0; i < totalSize; i++) {
            auto child = nativeModule_->getChildAt(handle_, i);
            // 获取子组件大小。
            auto childSize = nativeModule_->getMeasuredSize(child);
            // 布局子组件位置。
            nativeModule_->layoutNode(child, (selfSize.width - childSize.width) / 2,
                                      (selfSize.height - childSize.height) / 2);
        }
    }

    int32_t padding_ = 0;
};

} // namespace NativeModule

#endif // MYAPPLICATION_ARKUICUSTOMCONTAINERNODE_H
